home *** CD-ROM | disk | FTP | other *** search
/ System Booster / System Booster.iso / Archives / Drivers / vc_2_2.lha / ParNet / Source / unit_str.c < prev   
C/C++ Source or Header  |  1994-11-01  |  4KB  |  201 lines

  1. /*
  2. ** $Header: SRC:CVSROOT/Vector/ParNet/unit_str.c,v 1.1.1.1 1994/06/23 02:39:43 Barnard Exp $
  3. */
  4.  
  5. /*
  6. ** This code was originally written by Matthew Dillon and put into Public Domain
  7. **
  8. ** All changes concerning the adaption of Matt's original code to the
  9. ** Vector Connection I/O board are © 1991-1994 by Henning Schmiedehausen
  10. ** All rights for this changes are reserved. The original code is Public Domain
  11. **
  12. ** This code is distributed with the expressed written permission of Matthew
  13. ** Dillon (Thank you very much, Matt)
  14. **
  15. */
  16.  
  17. /*
  18.  *  UNIT_STR.C            STREAM PROTOCOL (not impl yet)
  19.  *
  20.  *                currently just datagram proto.
  21.  */
  22.  
  23. #include "defs.h"
  24.  
  25. #include "unit_str_protos.h"
  26. #include "unit_ctl_protos.h"
  27.  
  28. #include "parnet_protos.h"
  29. #include "task_protos.h"
  30.  
  31. #include <proto/exec.h>
  32. #include <stdlib.h>
  33. #include <stddef.h>
  34. #include <string.h>
  35.  
  36. #include "parnet_asm.h"
  37.  
  38. void StreamBeginIO();
  39. void StreamAbortIO();
  40. void StreamClose();
  41. void StreamData();
  42.  
  43. /*
  44.  *  Called under Forbid
  45.  */
  46.  
  47. void
  48. UnitStreamOpen(iob, unitnum, flags)
  49. Iob *iob;
  50. long unitnum;
  51. long flags;
  52. {
  53.     Unit *unit;
  54.  
  55.     if (unit = FindUnitForPort(iob->io_Port)) {
  56.     if (unit->BeginIO != StreamBeginIO) {
  57.         iob->io_Error = PPERR_PORT_IN_USE;
  58.         return;
  59.     }
  60.     } else {
  61.     unit = AllocUnit(iob, StreamBeginIO, StreamAbortIO, StreamData, StreamClose);
  62.     }
  63.     iob->io_Unit = unit;
  64.     ++unit->RefCnt;
  65. }
  66.  
  67.  
  68. void
  69. StreamClose(iob)
  70. Iob *iob;
  71. {
  72.     Unit *unit = iob->io_Unit;
  73.  
  74.     if (--unit->RefCnt == 0) {
  75.     FreeUnit(unit);
  76.     }
  77.     iob->io_Unit = NULL;
  78. }
  79.  
  80. /*
  81.  *  UnitStreamData() is called whenever a low level network operation
  82.  *            completes for the given unit.  cmd is:
  83.  *
  84.  *            'r'     received data packet
  85.  *            'w'     wrote data packet
  86.  *            'W'     timeout writing data packet
  87.  *
  88.  *            The routine is called with the unit locked.
  89.  */
  90.  
  91. void
  92. StreamData(cmd, packet, actual)
  93. Packet *packet;
  94. long actual;    /*  'w', 'W'    */
  95. {
  96.     Unit *unit = packet->io_Unit;
  97.     Iob *iob;
  98.     long n;
  99.  
  100.     switch(cmd) {
  101.     case 'r':
  102.     if (iob = (Iob *)RemHead(&unit->PendIOR)) {
  103.         iob->io_Flags &= ~IOF_QUEUED;
  104.  
  105.         n = actual;
  106.         iob->io_Actual = actual;
  107.         if (n < 0)
  108.         n = 0;
  109.         if (n > iob->io_Length) {
  110.         n = iob->io_Length;
  111.         iob->io_Error = PPERR_WARN_OVFLOW;
  112.         }
  113.         movmem((char *)packet->Data1, (char *)iob->io_Data, n);
  114.         if ((iob->io_Flags & IOF_QUICK) == 0)
  115.         ReplyMsg(&iob->io_Message);
  116.     }
  117.  
  118.     /*
  119.      *  Note that if no read requests are pending the datagram is
  120.      *  thrown away.
  121.      */
  122.  
  123.     FreeParPacket(packet);
  124.     break;
  125.     case 'W':
  126.     Remove(packet->iob);
  127.     iob->io_Flags &= ~IOF_QUEUED;
  128.     iob->io_Error = 1;
  129.     iob->io_Actual = actual;
  130.     if ((iob->io_Flags & IOF_QUICK) == 0)
  131.         ReplyMsg(&iob->io_Message);
  132.     FreeParPacket(packet);
  133.     break;
  134.     case 'w':
  135.     Remove(packet->iob);
  136.     iob->io_Flags &= ~IOF_QUEUED;
  137.     iob->io_Actual = actual;
  138.     if ((iob->io_Flags & IOF_QUICK) == 0)
  139.         ReplyMsg(&iob->io_Message);
  140.     FreeParPacket(packet);
  141.     break;
  142.     }
  143. }
  144.  
  145. void
  146. StreamBeginIO(iob)
  147. Iob *iob;
  148. {
  149.     Unit *unit = iob->io_Unit;
  150.     Packet *packet;
  151.  
  152.     iob->io_Error = 0;
  153.     iob->io_Actual = 0;
  154.     iob->io_Message.mn_Node.ln_Type = NT_MESSAGE;
  155.  
  156.     switch(iob->io_Command) {
  157.     case CMD_READ:
  158.     LockAddr(unit->UnitLock);
  159.     iob->io_Flags &= ~IOF_QUICK;
  160.     iob->io_Flags |= IOF_QUEUED;
  161.     AddTail(&unit->PendIOR, iob);
  162.     UnlockAddr(unit->UnitLock);
  163.     return;
  164.     case CMD_WRITE:
  165.     packet = AllocParPacket(iob, unit, iob->io_Data, iob->io_Length, NULL, 0);
  166.     LockAddr(unit->UnitLock);
  167.     AddTail(&unit->PendIOW, iob);
  168.     UnlockAddr(unit->UnitLock);
  169.  
  170.     QueuePacketForWrite(packet);
  171.     return;
  172.     default:
  173.     CtlBeginIO(iob);
  174.     return;
  175.     }
  176. }
  177.  
  178. /*
  179.  *  Abort a read or write request.  Currently only read requests may be
  180.  *  aborted.
  181.  */
  182.  
  183. void
  184. StreamAbortIO(iob)
  185. Iob *iob;
  186. {
  187.     if (iob->io_Command == CMD_READ) {
  188.     LockAddr(iob->io_Unit->UnitLock);
  189.     if ((iob->io_Flags & (IOF_QUEUED|IOF_RUN)) == IOF_QUEUED) {
  190.         Remove(iob);
  191.         UnlockAddr(iob->io_Unit->UnitLock);
  192.         iob->io_Flags &= ~IOF_QUEUED;
  193.         iob->io_Error = -1;     /*    ??? */
  194.         ReplyMsg(&iob->io_Message);
  195.     } else {
  196.         UnlockAddr(iob->io_Unit->UnitLock);
  197.     }
  198.     }
  199. }
  200.  
  201.